/**
 * 通过hash Table实现一个ES6的Map方法
 * Map的底层数据结构是散列表，即：数组+链表。创建的时候初始化一个数组，每个节点可以为一个链表，即拉链法
*/

function MaxMap() {
  this.init();
}

/** 初始化 */
MaxMap.prototype.init = function() {
  this.size = 0; // Map的长度
  this.bucket = new Array(8); // bucket:桶
  // 数组每一个都创建一个链表头
  for(var i = 0; i < 8; i++) {
    this.bucket[i] = {};
    this.bucket[i].next = null;
  }
}

/** hash方法，获取对应的下标 */
MaxMap.prototype.hash = function(key) {
  let idx = 0;
  if (typeof key == "string") { // 获取unicode编码
    for (let i = 0; i < 10; i ++) {
      i += isNaN(key.charAt(i)) ? 0 : key.charAt(i);
    }
  } else if (key == "undefined") {
    idx = 1;
  } else if (typeof key == "object") {
    idx = 0;
  } else if (typeof key == "number") {
    idx = key % this.bucket.length;
  }
  return idx % this.bucket.length;
}

/** 插入 */
MaxMap.prototype.set = function(key, value) {
  // 1.拿到插入的链表下标
  const idx = this.hash(key);
  let target = this.bucket[idx];
  while(target.next) {
    if (target.next.key == key) { // 更新
      target.next.value = value;
      return this;
    }
    target = target.next;
  }
  // 新赋值
  target.next = {
    key,
    value,
    next: null,
  }
  this.size++;
  return this;
}

/** 获取 */
MaxMap.prototype.get = function(key) {
  const idx = this.hash(key);
  let target = this.bucket[idx];
  while(target) {
    if (target.key == key) {
      return target.value;
    }
    target = target.next;
  }
  return;
}

MaxMap.prototype.has = function(key) {
  const idx = this.hash(key);
  let target = this.bucket[idx];
  while(target) {
    if (target.key == key) {
      return true;
    }
    target = target.next;
  }
  return false;
}
/** 删除 */
MaxMap.prototype.delete = function(key) {
  const idx = this.hash(key);
  let target = this.bucket[idx];
  while(target.next) {
    if (target.next.key == key) {
      target.next = target.next.next;
      return true;
    }
    target = target.next;
  }
  return false;
}


const map = new MaxMap();
map.set(1, "123")
console.info(map, map.size);
console.info(map.get(1))
console.info(map.get(13))
console.info(map.has(12), map.has(1))
console.info(map.delete(1), map.has(1))

var obj = {
  1: "fjad 0",
  a: 1232,
  b: "343jkd"
}
obj.x = 123;
console.info(Object.keys(obj))